home *** CD-ROM | disk | FTP | other *** search
- Path: fohnix.metronet.com!not-for-mail
- From: milam@fohnix.metronet.com (Stan Milam)
- Newsgroups: comp.lang.c
- Subject: Re: embedded strtok() calls on different strings?
- Date: 8 Feb 1996 20:57:58 -0600
- Organization: Texas Metronet, Inc (login info (214/488-2590 - 817/571-0400))
- Message-ID: <4fed7m$sk2@fohnix.metronet.com>
- References: <DMGrn7.1Bx0@CompStar.bnr.ca>
- NNTP-Posting-Host: fohnix.metronet.com
- X-Newsreader: TIN [version 1.2 PL2]
-
- tzinck@bnr.ca wrote:
-
- : Hello.
-
-
- : I want to do the following:
-
-
- : char *string1="This is string one";
- : char *string2="This is string two";
-
- : void *vp1;
- : void *vp2;
-
- : vp1 = strtok(string1," ");
-
- : while (vp1 != NULL){
- : printf("Tok1 = %s\n", (char *) vp1);
-
- : vp2 = strtok(string2," ");
- : while (vp2!=NULL){
- : printf("Tok2 = %s\n", (char *) vp2);
- : vp2 = strtok(NULL, " ");
- : }
-
- : vp1 = strtok(NULL, " ");
- : }
-
- : But the output is :
- : Tok1 = This
- : Tok2 = This
- : Tok2 = is
- : Tok2 = string
- : Tok2 = two
-
-
- : as vp1 gets corrupted. Any thoughts ?
-
- : -Tom
- :
-
- Why yes. The strtok() function uses an internal static pointer to the initial
- string used in the very first call. All subsequent calls to strtok() use
- this pointer to find the next token and this continues until all tokens
- are exhausted *OR* strtok() is called with a new string. When this happens
- the internal pointer now points to the new string with no way to get back
- to the first one you started with. So, what you are trying to accomplish
- cannot be done with strtok().
-
- Also, strtok() does not handle empty tokens very well. Here are a couple
- of alternative solutions to strtok() that I have come up with. I really
- like strptok() the best. Enjoy!
-
- Regards,
- Stan Milam.
-
- /**********************************************************************/
- /* File Id: strparse.c. */
- /* Author: Stan Milam. */
- /* Date Written: 20-Feb-1995. */
- /* Description: */
- /* The str_parse() function is used to extract fields from de- */
- /* limited ASCII records. It is designed to deal with empty fields*/
- /* in a logical manner and meant to preclude the use of strtok() */
- /* for such purposes! */
- /* */
- /* Arguments: */
- /* char **str - The address of a pointer which in turn */
- /* points to the string being parsed. The */
- /* actual pointer is modified with each call to*/
- /* point to the beginning of the next field. */
- /* char *delimiters - The address of the string containing the */
- /* characters used to delimit the fields within*/
- /* the record. */
- /* */
- /* Return Value: */
- /* A pointer of type char which points to the current field in the*/
- /* parsed string. If an empty field is encountered the address */
- /* is that of an empty string (i.e. "" ). When there are no more */
- /* fields in the record a NULL pointer value is returned. */
- /* */
- /**********************************************************************/
-
- #include <stddef.h>
- #include <string.h>
-
- char *str_parse( char **str, char *delimiters ) {
-
- char *head, *tail, *rv;
-
- if ( *str == NULL || **str == '\0' )
- rv = NULL;
- else if ( delimiters == NULL || *delimiters == '\0' )
- rv = NULL;
- else {
- rv = head = *str;
- if ( ( tail = strpbrk( head, delimiters ) ) == NULL )
- *str = head + strlen( head );
- else {
- *tail = '\0';
- *str = tail + 1;
- }
- }
- return rv;
- }
-
- #ifdef TEST
- #include <stdio.h>
- #include <assert.h>
-
- int main( void ) {
-
- char *wrk, *rv;
- char delimiters[] = ":;";
- char wrkstr[] = "1:2::4:;6:7";
-
- wrk = "";
- assert( str_parse( NULL, delimiters ) == NULL );
- assert( str_parse( &wrk, delimiters ) == NULL );
-
- wrk = wrkstr;
- assert( str_parse( &wrk, NULL ) == NULL );
- assert( str_parse( &wrk, "" ) == NULL );
-
- while((rv = str_parse( &wrk, delimiters )))
- puts( rv );
-
- return 0;
- }
- #endif
-
-
- /*FILE*****************************************************************/
- /* File Id: strptok.c. */
- /* Author: Stan Milam. */
- /* Date Written: 25-Apr-95. */
- /* Description: */
- /* Implement a strtok() like function which preserves the original*/
- /* string. */
- /* */
- /*****************************************************************FILE*/
-
- #include <stddef.h>
- #include <string.h>
-
- /*FUNCTION*************************************************************/
- /* Name: strptok(). */
- /* */
- /* Description: */
- /* This function implements a strtok() like function which pre- */
- /* serves the original string and copies tokens into a programmer */
- /* supplied buffer. */
- /* */
- /* Arguments: */
- /* char *dest - Address of buffer where token is to be copied. */
- /* char *src - Address of source buffer where tokens are to be */
- /* extracted. */
- /* char *brk - "Break" characters which delimit tokens. */
- /* */
- /* Return Value: */
- /* NULL when the end of the string is encounted or when the src */
- /* argument is NULL or empty. Otherwise the address just beyond */
- /* the last token found in the source string. */
- /* */
- /*************************************************************FUNCTION*/
-
- char *strptok( char *dest, char *src, char *brk ) {
-
- unsigned len;
- char *rv, *wrk;
-
- /******************************************************************/
- /* Make sure destination is empty and check for a valid source. */
- /******************************************************************/
-
- dest[0] = '\0';
- if ( src == NULL || *src == '\0' )
- rv = NULL;
-
- /******************************************************************/
- /* If there are not any break characters set rv to NULL and copy */
- /* the remaining characters to the destination. */
- /******************************************************************/
-
- else if (( wrk = strpbrk(src, brk) ) == NULL) {
- rv = NULL;
- strcpy( dest, src );
- }
-
- /******************************************************************/
- /* If the first character of source is a break character then */
- /* skip over it. */
- /******************************************************************/
-
- else if ( src == wrk )
- rv = src + 1;
-
- /******************************************************************/
- /* Found a token! Compute return value, length of token and copy */
- /* it to destination making sure it is null terminated. */
- /******************************************************************/
-
- else {
- rv = wrk + 1;
- len = wrk - src;
- strncpy( dest, src, len )[len] = '\0';
- }
- return rv;
- }
-
- #ifdef TEST
- #include <stdio.h>
- int main( void ) {
-
- char dest[50] = "", *rv;
- char *src = ":tsdsstm:243::0:Stan Milam,3730442330,Y:/u/tsdsstm/ksh";
-
- rv = strptok( dest, NULL, ":" );
- rv = strptok( dest, "", ":" );
-
- rv = strptok( dest, src, ":" );
- while ( rv || dest[0] ) {
- printf(":%s:\n", dest);
- rv = strptok( dest, rv, ":" );
- }
- }
- #endif
-